using System.Linq;
using Common.Commands;
using Common.Commands.ContactCommands;
using Core.Domain.Model;
using Core.Infrastructure.CustomExceptions;
using Dto.ApiResponses.ContactResponses;
using Sanelib.Common.Helpers;
using Sanelib.DataOperation;

namespace Core.Processors.ContactProcessors
{
    public class AddContactProcessor : ICommandProcessor<AddContact>
    {
        private readonly IRepository<Contact> _contactRepository;

        public AddContactProcessor(IRepository<Contact> contactRepository)
        {
            _contactRepository = contactRepository;
        }

        public dynamic Process(AddContact command)
        {
            EnsureSameNameContact(command);
            EnsureSameEmailContact(command);

            var contact = new Contact
            {
                Id = command.Id,
                Name = command.Name,
                LastName = command.LastName,
                FirstName = command.FirstName,
                NameTitle = command.NameTitle,
                Email = command.Email,
                Phone = command.Phone,
                Mobile = command.Mobile,
                CompanyName = command.CompanyName,
                Designation = command.Designation,
                Description = command.Description,
                ImageData = command.ImageData,
                CreatedBy = command.UserId
            };
            _contactRepository.Add(contact);

            return new ContactResponse
            {
                Id = command.Id,
                Name = command.Name,
                Description = command.Description,
                ImageData = command.ImageData
            };
        }

        private void EnsureSameNameContact(AddContact command)
        {
            var alradyAddedContact = _contactRepository.GetAllFor(Property.Of<Contact>(x => x.Name), command.Name).SingleOrDefault();

            if (alradyAddedContact == null) return;
            throw new DomainProcessException(string.Format("Contact Name should not be duplicated. Already available contact with this name : {0}", command.Name));
        }

        private void EnsureSameEmailContact(AddContact command)
        {
            var alradyAddedContactWithSameEmail = _contactRepository.GetAllFor(Property.Of<Contact>(x => x.Email), command.Email).SingleOrDefault();

            if (alradyAddedContactWithSameEmail == null) return;
            throw new DomainProcessException(string.Format("Contact Email should not be duplicated. Already available contact with this name : {0}", command.Name));
        }
    }
}
